package com.yishuifengxiao.common.crawler.scheduler;

import java.util.Map;
import java.util.WeakHashMap;

import org.apache.commons.lang3.StringUtils;

import com.yishuifengxiao.common.crawler.cache.RequestCache;
import com.yishuifengxiao.common.crawler.domain.constant.CrawlerConstant;
import com.yishuifengxiao.common.crawler.domain.entity.Request;
import com.yishuifengxiao.common.crawler.domain.model.SiteRule;

/**
 * 资源调度器装饰者<br/>
 * 负责资源的调度管理工作<br/>
 * 功能如下：<br/>
 * 1. 接收所有未过滤的链接并存储起来<br/>
 * 2. 从资源池中获取一个链接<br/>
 * 3. 判断资源是否需要存储<br/>
 * 
 * @author yishui
 * @date 2019年11月26日
 * @version 1.0.0
 */
public class SchedulerDecorator implements Scheduler {
	/**
	 * 请求缓存器，负责缓存所有需要抓取的网页的URL(包括历史记录)和已经爬取的url集合
	 */
	private RequestCache requestCache;
	/***
	 * 真实的资源调度器
	 */
	private Scheduler scheduler;
	/**
	 * 站点信息
	 */
	private SiteRule siteRule;

	@Override
	public void push(Request request) {

		if (this.needStore(request)) {
			// 补全请求信息
			request.setConnectTimeout(this.siteRule.getConnectTimeout());
			request.setCookies(this.siteRule.getCookiValues());
			request.setHeaders(this.siteRule.getAllHeaders());
			request.setUserAgent(this.siteRule.getAutoUserAgent());
			request.setMethod("get");
			request.setPriority(0L);

			if (StringUtils.isNotBlank(siteRule.getReferrer())) {
				request.setReferrer(siteRule.getReferrer());
			}

			Map<String, Object> extras = new WeakHashMap<>();
			extras.put("cacheControl", this.siteRule.getCacheControl());
			extras.put("cookieSpec", this.siteRule.getCookieSpec());
			extras.put("cookieSpec", this.siteRule.isRedirectsEnabled());
			extras.put("relativeRedirectsAllowed", this.siteRule.isRelativeRedirectsAllowed());
			extras.put("circularRedirectsAllowed", this.siteRule.isCircularRedirectsAllowed());
			extras.put("maxRedirects", this.siteRule.getMaxRedirects());
			extras.put("contentCompressionEnabled", this.siteRule.isContentCompressionEnabled());
			extras.put("normalizeUri", this.siteRule.isNormalizeUri());
			request.setExtras(extras);

			// 存储到待抓取集合中
			this.scheduler.push(request);
			// 存储在历史记录集之中
			this.requestCache.save(new StringBuffer(CrawlerConstant.REQUEST_HOSTORY).append(this.getName()).toString(),
					request);
		}

	}

	/**
	 * 判断链接是否符合提取规则
	 * 
	 * @param url
	 * @return
	 */
	private boolean needStore(Request request) {
		if (null == request) {
			return false;
		}
		// 在历史链接记录集不存在时才处理
		return !requestCache.exist(CrawlerConstant.REQUEST_HOSTORY + this.getName(), request);
	}

	@Override
	public Request poll() {

		return this.scheduler.poll();
	}

	@Override
	public String getName() {
		return this.scheduler.getName();
	}

	@Override
	public void clear() {
		this.scheduler.clear();

	}

	public SchedulerDecorator(RequestCache requestCache, Scheduler scheduler, SiteRule siteRule) {
		this.requestCache = requestCache;
		this.scheduler = scheduler;
		this.siteRule = siteRule;
	}

}
